<template>
  <div class="ranking-list">
    <audio
        v-show="false"
        controls
        :volume="store.audioOptions.volume"
        @timeupdate="timeupdate"
        ref="audio"
        @canplay="canplay"
        @seeking="seeking"
        @pause="audioPause"
        @play="audioPlay"
        @canPlayType="error"
    >
      <source :src="store.playlistInfo[store.songUrlIndex]?.src" type="audio/mpeg" @error="error">
    </audio>
    <transition
        enter-active-class="animate__animated animate__zoomIn"
        leave-active-class="animate__animated animate__zoomOut"
    >
      <div v-if="playerExamples" class="relative">
        <lyric class="player-list" :is-h4="true" v-if="isShowLyric " @closeLyrics="showLyric" />
        <player-list ref="playerList" :player-list="store.playlistInfo" @specifyPlay="specifyPlay" class="player-list"/>
        <div class="yu-bgColor-tew-only w-full">
          <div class="player  flex items-center w-full justify-center ">
            <div class="flex items-center" style="font-size: 20px;">
              <!-- 上一首 -->
              <Prev :active-btn-style="activeBtnStyle" @prev="prev" />
              <!-- 后退5s -->
              <Backward :active-btn-style="activeBtnStyle" @backward="backward"/>
              <!-- 播放暂停 -->
              <StartStop :active-btn-style="activeBtnStyle" @startStop="startStop" />
              <!-- 前进5s -->
              <Forward :active-btn-style="activeBtnStyle" @forward="forward"/>
              <!-- 下一首 -->
              <Next :active-btn-style="activeBtnStyle" @next="next"/>
              <div class="info flex items-center p-1 justify-between" @click="jumpPlayMusicInfo">
                <van-image class="w-10 h-10" fit="cover" :src="store.playlistInfo[store.songUrlIndex]?.al?.picUrl"></van-image>
              </div>
            </div>
            <div class="flex flex-col box-border" style="width: 50%;">
              <div class="w-3/4 truncate">
                <span class="p-1  cursor-pointer yu-textColor-hover" @click="jumpPcSongDetail(store.playlistInfo[store.songUrlIndex].id)">{{ store.playlistInfo[store.songUrlIndex]?.name }}</span>
                -
                <span class="p-1  cursor-pointer yu-textColor-hover" @click.stop="jumpArtistDetails( store.playlistInfo[store.songUrlIndex].ar[0].id)">{{ store.playlistInfo[store.songUrlIndex]?.ar[0]?.name }}</span>
              </div>
              <div class="flex item-center items-baseline ml-2">
                <!-- 进度条 -->
                <Slider
                    :play-progress-bar="store.audioOptions.playProgressBar"
                    :progress-bar-max="store.audioOptions.progressBarMax"
                    @onChange="onChange"
                    @dragStart="dragStart"
                />
                <span class="text-sm pr-2">{{ store.audioOptions.currentlyPlaying }}/{{ store.audioOptions.totalPlayTime }}</span>
                <span @click="packUp" v-if="store.isFlag"
                      class="w-15 text-center i-mdi-arrow-expand-up yu-textColor-hover cursor-pointer"></span>
                <div
                    v-if="store.isFlag"
                    class="volume inline-block relative cursor-pointer"
                    @mousemove="mousemoveVolume"
                    @mouseleave="mouseleaveVolume"
                    @click="store.audioOptions.volume === 0 ? store.audioOptions.volume = 1 : store.audioOptions.volume = 0"
                >
                  <span class="inline-block w-4  yu-textColor-hover " :class="store.audioOptions.volume === 0 ? 'i-mdi-volume-off': 'i-mdi-volume' "/>
                  <van-slider
                      v-show="store.audioOptions.isVolume"
                      vertical
                      :reverse="true"
                      class="van-slider"
                      style=""
                      :step="0.1"
                      :active-color="store.theme.HoverBgColor"
                      :inactive-color="store.theme.bgColor"
                      max="1"
                      v-model="store.audioOptions.volume"
                  >
                    <template #button>
                      <div class="w-2 h-2 bg-white rounded-full shadow-md"></div>
                    </template>
                  </van-slider>
                </div>
                <div v-if="store.isFlag" class="playlist flex items-center cursor-pointer yu-textColor-hover ml-2" @click="startPlayerList">
                  <span class="inline-block i-mdi-list-box"></span>
                  <span class="text-sm">{{ store.privilegesTracks.length }}</span>
                </div>
                <div v-if="store.isFlag" class="ml-2 cursor-pointer yu-textColor-hover" @click="showLyric">
                  <span class="i-mdi-file-word-outline inline-block"></span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- pc端收起 -->
      <div
          @click="packUp"
          v-else
          class="bg-red absolute bottom-3 right-3 hover:animate-none m-1 overflow-hidden w-15 h-15 shadow-xl rounded-full flex flex-clo justify-center cursor-pointer items-center"
          :class="store.audioOptions.isPaused ? 'animate-none' : 'animate-spin' "
      >
        <van-image fit="cover" :src="store.playlistInfo[store.songUrlIndex]?.al?.picUrl"></van-image>
      </div>
    </transition>
  </div>
</template>

<script setup>
import {onMounted, reactive, ref, toRefs, watchEffect} from "vue"
import {useStore} from "@/store/index";
import PlayerList from './components/PlayerList/index.vue'
import Lyric from '@/components/Lyric/index.vue'
// 秒转换为分秒
import { secondsToMinutes } from "@/utils/index"
import {useRouter} from "vue-router";
// 播放器进度条
import Slider from './components/Slider/index.vue'
// 播放暂停
import StartStop from './components/StartStop/index.vue'
// 上一首
import Prev from './components/Prev/index.vue'
// 下一首
import Next from './components/Next/index.vue'
// 后退5s
import Backward from './components/Backward/index.vue'
// 前进5s
import Forward from './components/Forward/index.vue'



onMounted(() => {
  playerParameters.afterRender = true
})

// 播放器样式
const playerParameters = reactive({
  activeBtnStyle: ['transition cursor-pointer yu-textColor-hover mr-1 ml-1 '],
  playerExamples: true, // 播放器收起和展示
  isShowLyric: false, // 展示歌词
  afterRender: false
})

const router = useRouter()
const store = useStore()

let {
  activeBtnStyle,
  playerExamples,
  isShowLyric,
  afterRender
} = toRefs(playerParameters)

// refs实例
const audio = ref()

onMounted(() => {
  // 渲染完成播放音乐
  // startStop()
})

// 监听音乐播放报错
const error = () => {
  // 由于音乐播放器在播放时有时候请求会403，
  // 所以需要重新请求，当前播放的音乐如果重新请求之后还是不能播放就切换到下一首并在把这个值重置为FALSE
  if (!store.limitRefresh) {
    // 如果报错了 就重新请求播放音乐的数据 TODO:暂时先这样如果出问题了该改（已解决）
    store.getSongUrl()
    store.limitRefresh = true
  } else {
    // 播放下一首
    nextAction()
    store.limitRefresh = false
  }
}

/**
 *@params：
 *@desc：pc端点击收起和放开
 *@author：羽
 *@date 2022/08/02 17:07:14
 */
const packUp = () => {
  playerParameters.playerExamples = !playerParameters.playerExamples
}
// 音频加载完成时触发
const canplay = (e) => {
  // 将总播放时间秒转为分秒格式，赋值给总时间
  store.audioOptions.totalPlayTime = secondsToMinutes(e.target.duration)
  // 设置进度条最大长度
  store.audioOptions.progressBarMax = e.target.seekable.end(0)
  // 如果重置之后音乐可以播放就将这个设为false
  if (store.limitRefresh) {
    store.limitRefresh = false
  }
}


// 移动播放位置触发
const seeking = () => {
  // console.log('seeking', e)
}


// 音乐播放时会触发
const audioPlay = (e) => {
  // 为了改变icon
  store.audioOptions.isPaused = false
  // 播放时将存储的播放时间赋值给音乐播放时间
  e.target.currentTime = store.audioOptions.currentTime
}

// 音乐暂停的时候会触发
const audioPause = () => {
  // 当audio为null时不允许赋值
  if (audio.value)
  // 为了改变icon
  store.audioOptions.isPaused = true
}


// 播放过程中触发
const timeupdate = (e) => {

  // console.log(e.target.seekable.end(0))
  // 切换歌单的时候会找不到ended
  if (audio.value?.ended) {
    nextAction()
  } else {
    // 设置当前歌词播放位置
    store.playerTime = e.target.currentTime
    store.audioOptions.currentTime = e.target.currentTime
  }
  // 当前播放时间
  setPlayTime(e)
}

// 操作下一首
const nextAction = () => {
  // songUrlIndex + 1 是否大于音乐数据的长度 - 1 大于的话就从0播放，不大于就下一首
  if ((store.songUrlIndex + 1) < store.playlistInfo.length) {
    store.songUrlIndex += 1
  } else {
    store.songUrlIndex = 0
  }
  // 进度条重置为零
  store.audioOptions.playProgressBar = 0
  // 重新加载音乐
  playLoad()
}

// 当前播放时间
const setPlayTime = (e) => {
  // 防止切换下一首歌报错，当seekable加载完成时length === 1
  if (e.target.seekable.length === 1) {
    let currentTime = e.target.currentTime.toFixed(0)
    let seekableEnd = e.target.seekable.end(0).toFixed(0)
    // 播放中如果当前播放的时间小于等于歌曲总时间就触发
    if (Number(currentTime) <= Number(seekableEnd)) {
      // 歌曲播放时进度条跟着移动，当移动进度条时不允许在触发下面，不移动进度条触发下面
      if (store.audioOptions.setProgressBarStatus) store.audioOptions.playProgressBar = Number(currentTime)
      // 歌曲以播放时间
      store.audioOptions.currentlyPlaying = secondsToMinutes(currentTime)
    }
  }
}

// 重新加载音乐
const playLoad = () => {
  // 重新加载
  audio.value.load()
  audio.value.play()
}

// 监听下标的变化，用来获取歌词
watchEffect(() => {
  if (store.songUrlIndex >= 0  && store.playlistInfo.length > 0 && !(store.playlistInfo[store.songUrlIndex]?.noLyric)) {
    store.getLyric(store.playlistInfo[store.songUrlIndex]?.id)
  } else { // 电台是没有歌词的
    store.lyric = ''
  }
})

/**
 *@params：
 *@desc：操作按钮，播放、暂停、下一首，上一首、快进、倒退、拖拽进度条
 *@author：羽
 *@date 2022/08/02 12:10:43
 */

// 播放
const startStop = () => {
  if (audio.value.paused && audio.value) {
    // audio.value.load()
    audio.value.play()
  } else {
    audio.value.pause()
  }
}

// 上一首
const prev = () => {
  if ((store.songUrlIndex - 1) >= 0) {
    store.songUrlIndex -= 1
  } else {
    store.songUrlIndex = store.playlistInfo.length - 1
  }
  // 进度条重置为零
  store.audioOptions.playProgressBar = 0
  // 重新加载音乐
  playLoad()
}
// 下一首
const next = () => {
  nextAction()
}

// 快进5s
const forward = () => {
  // 当快进长度超过总时长是不允许
  if ((audio.value.currentTime + 5) < audio.value.seekable.end(0))
    audio.value.currentTime += 5
}
// 回退5s
const backward = () => {
  if (audio.value.currentTime - 5 > 0)
    audio.value.currentTime = Number(audio.value.currentTime) - 5
}

// 进度条被改变时触发
const onChange = (value) => {
  // 拖动播放播放进度条触发，将拖的进度条数据赋值给currentTime
  audio.value.currentTime = value
  // 拖拽结束之后重可以赋值
  store.audioOptions.setProgressBarStatus = true
}
// 开始拖拽时触发
const dragStart = () => {
  store.audioOptions.setProgressBarStatus = false
}

// 鼠标移动到音量打开音量控件
const mousemoveVolume = () => {
  store.audioOptions.isVolume = true
}
// 鼠标离开到音量关闭音量控件
const mouseleaveVolume = () => {
  store.audioOptions.isVolume = false
}
// 设置播放哪首
const specifyPlay = (index) => {
  store.songUrlIndex = index
  playLoad()
}
// 播放列表实例
const playerList = ref(null)

// 打开音乐播放列表
const startPlayerList = () => {
  playerList.value.closeORStart()
}

// 关闭或展示歌词
const showLyric = () => {
  playerParameters.isShowLyric = !playerParameters.isShowLyric
}
/**
 *@params：
 *@desc：点击播放歌曲的头像跳转到播放详情，只有移动端可以
 *@author：羽
 *@date 2022/08/09 11:01:39
 */
const jumpPlayMusicInfo = () => {
  if (!store.isFlag) {
    router.push({
      path: '/mobile-details-song'
    })
  }
}

// 点击播放器档期歌曲name跳转到详情
const jumpPcSongDetail = (id) => {
  router.push({
    path: '/pc-song-detail',
    query: {
      id
    }
  })
}

// 跳转到歌手详情
const jumpArtistDetails = (id) => {
  router.push({
    path: '/artist',
    query: {
      id
    }
  })
}
// 清空正在播放的数据
const playingNull = () => {
  startStop()
  // audio.value.src = ''
  audio.value.remove()
  store.audioOptions.totalPlayTime = '00:00' // 总播放時間
  store.audioOptions.currentlyPlaying = '00:00' // 当前播放时间
  store.audioOptions.playProgressBar = 0
  store.audioOptions.currentTime = 0 // 当前播放时间
  // 关闭列表弹窗
  playerList.value.closeORStart()
}

// 讲事件抛出给其他组件调用
defineExpose({
  startStop,
  forward,
  backward,
  prev,
  next,
  onChange,
  dragStart,
  playLoad,
  playingNull
})
</script>

<style scoped lang="scss">
@import "./index.scss";
// 只是二级背景
.yu-bgColor-tew-only {
  background-color: v-bind('store.theme.secondaryBgColor');
  color: v-bind('store.theme.textColor') !important;
}

// 字体颜色
.yu-color-text {
  color: v-bind('store.theme.textColor');
}

// hover字体颜色
.yu-textColor-hover {
  &:hover {
    color: v-bind('store.theme.hoverTextColor')!important;
  }
}
</style>

